const db = uniCloud.database();
const dbCmd = db.command;
const refundCollection = db.collection('refund');

module.exports = {
  _before: function() {
    // 通用前置处理
  },
  
  /**
   * 获取退费记录列表
   * @param {Object} params - 查询参数
   * @param {String} params.student_id - 学生ID（可选）
   * @param {String} params.course_id - 课程ID（可选）
   * @param {String} params.enrollment_id - 报名ID（可选）
   * @param {Number} params.status - 状态（可选）
   * @param {String} params.start_date - 开始日期（可选）
   * @param {String} params.end_date - 结束日期（可选）
   * @param {Number} params.page - 页码
   * @param {Number} params.pageSize - 每页数量
   * @returns {Object} 退费记录列表和总数
   */
  async getRefundList(params = {}) {
    const { 
      student_id, 
      course_id, 
      enrollment_id, 
      status, 
      start_date, 
      end_date,
      page = 1, 
      pageSize = 10 
    } = params;
    
    // 构建查询条件
    const query = {};
    if (student_id) query.student_id = student_id;
    if (course_id) query.course_id = course_id;
    if (enrollment_id) query.enrollment_id = enrollment_id;
    if (status !== undefined) query.status = status;
    
    // 日期范围查询
    if (start_date && end_date) {
      const startDate = new Date(start_date);
      startDate.setHours(0, 0, 0, 0);
      
      const endDate = new Date(end_date);
      endDate.setHours(23, 59, 59, 999);
      
      query.refund_date = dbCmd.gte(startDate).and(dbCmd.lte(endDate));
    }
    
    // 查询总数
    const countResult = await refundCollection.where(query).count();
    const total = countResult.total;
    
    // 查询分页数据
    const list = await refundCollection
      .aggregate()
      .match(query)
      .lookup({
        from: 'student',
        localField: 'student_id',
        foreignField: '_id',
        as: 'student'
      })
      .lookup({
        from: 'course',
        localField: 'course_id',
        foreignField: '_id',
        as: 'course'
      })
      .project({
        _id: 1,
        student_id: 1,
        course_id: 1,
        enrollment_id: 1,
        payment_id: 1,
        amount: 1,
        refund_date: 1,
        refund_reason: 1,
        refund_method: 1,
        status: 1,
        period_start: 1,
        period_end: 1,
        remarks: 1,
        create_date: 1,
        update_date: 1,
        student: { $arrayElemAt: ['$student', 0] },
        course: { $arrayElemAt: ['$course', 0] }
      })
      .skip((page - 1) * pageSize)
      .limit(pageSize)
      .sort({
        refund_date: -1
      })
      .end()
      .then(res => res.data);
    
    return {
      list,
      total,
      page,
      pageSize
    };
  },
  
  /**
   * 获取退费记录详情
   * @param {String} id - 退费记录ID
   * @returns {Object} 退费记录详情
   */
  async getRefundDetail(id) {
    if (!id) throw new Error('退费记录ID不能为空');
    
    const refund = await refundCollection
      .aggregate()
      .match({
        _id: id
      })
      .lookup({
        from: 'student',
        localField: 'student_id',
        foreignField: '_id',
        as: 'student'
      })
      .lookup({
        from: 'course',
        localField: 'course_id',
        foreignField: '_id',
        as: 'course'
      })
      .lookup({
        from: 'enrollment',
        localField: 'enrollment_id',
        foreignField: '_id',
        as: 'enrollment'
      })
      .lookup({
        from: 'payment',
        localField: 'payment_id',
        foreignField: '_id',
        as: 'payment'
      })
      .project({
        _id: 1,
        student_id: 1,
        course_id: 1,
        enrollment_id: 1,
        payment_id: 1,
        amount: 1,
        refund_date: 1,
        refund_reason: 1,
        refund_method: 1,
        status: 1,
        period_start: 1,
        period_end: 1,
        remarks: 1,
        create_date: 1,
        update_date: 1,
        student: { $arrayElemAt: ['$student', 0] },
        course: { $arrayElemAt: ['$course', 0] },
        enrollment: { $arrayElemAt: ['$enrollment', 0] },
        payment: { $arrayElemAt: ['$payment', 0] }
      })
      .end()
      .then(res => res.data[0]);
    
    if (!refund) throw new Error('退费记录不存在');
    
    return refund;
  },
  
  /**
   * 创建退费记录
   * @param {Object} data - 退费数据
   * @returns {Object} 创建结果
   */
  async createRefund(data) {
    // 验证必填字段
    const { 
      student_id, 
      course_id, 
      enrollment_id, 
      payment_id,
      amount, 
      refund_date,
      refund_reason,
      refund_method,
      period_start,
      period_end
    } = data;
    
    if (!student_id) throw new Error('学生ID不能为空');
    if (!course_id) throw new Error('课程ID不能为空');
    if (!enrollment_id) throw new Error('报名ID不能为空');
    if (!payment_id) throw new Error('缴费记录ID不能为空');
    if (amount === undefined || amount <= 0) throw new Error('退费金额必须大于0');
    if (!refund_date) throw new Error('退费日期不能为空');
    if (!refund_reason) throw new Error('退费原因不能为空');
    if (![1, 2, 3, 4].includes(refund_method)) throw new Error('退费方式不正确');
    if (!period_start) throw new Error('退费周期开始日期不能为空');
    if (!period_end) throw new Error('退费周期结束日期不能为空');
    
    // 检查缴费记录是否存在
    const payment = await db.collection('payment')
      .doc(payment_id)
      .get()
      .then(res => res.data[0]);
    
    if (!payment) throw new Error('缴费记录不存在');
    if (payment.status !== 1) throw new Error('缴费记录状态不正确，无法创建退费记录');
    
    // 检查缴费记录的金额是否足够退费
    if (payment.amount < amount) {
      throw new Error('退费金额不能大于原缴费金额');
    }
    
    // 检查学生、课程和报名ID是否与缴费记录匹配
    if (payment.student_id !== student_id) {
      throw new Error('学生ID与缴费记录不匹配');
    }
    
    if (payment.course_id !== course_id) {
      throw new Error('课程ID与缴费记录不匹配');
    }
    
    if (payment.enrollment_id !== enrollment_id) {
      throw new Error('报名ID与缴费记录不匹配');
    }
    
    // 验证日期范围
    const startDate = new Date(period_start);
    const endDate = new Date(period_end);
    
    if (startDate > endDate) {
      throw new Error('退费周期开始日期不能晚于结束日期');
    }
    
    // 创建退费记录
    const result = await refundCollection.add({
      ...data,
      status: data.status || 0, // 默认为待处理状态
      create_date: new Date(),
      update_date: new Date()
    });
    
    return {
      id: result.id,
      success: true
    };
  },
  
  /**
   * 更新退费记录
   * @param {String} id - 退费记录ID
   * @param {Object} data - 更新数据
   * @returns {Object} 更新结果
   */
  async updateRefund(id, data) {
    if (!id) throw new Error('退费记录ID不能为空');
    
    // 检查退费记录是否存在
    const refund = await refundCollection.doc(id).get().then(res => res.data[0]);
    if (!refund) throw new Error('退费记录不存在');
    
    // 检查并验证日期范围
    if (data.period_start && data.period_end) {
      const startDate = new Date(data.period_start);
      const endDate = new Date(data.period_end);
      
      if (startDate > endDate) {
        throw new Error('退费周期开始日期不能晚于结束日期');
      }
    }
    
    // 更新退费记录
    await refundCollection.doc(id).update({
      ...data,
      update_date: new Date()
    });
    
    return {
      id,
      success: true
    };
  },
  
  /**
   * 处理退费申请
   * @param {String} id - 退费记录ID
   * @param {Number} status - 退费状态：1 已退费，2 拒绝退费
   * @param {String} remarks - 处理备注
   * @returns {Object} 处理结果
   */
  async processRefund(id, status, remarks) {
    if (!id) throw new Error('退费记录ID不能为空');
    if (![1, 2].includes(status)) throw new Error('退费状态不正确');
    
    // 检查退费记录是否存在
    const refund = await refundCollection.doc(id).get().then(res => res.data[0]);
    if (!refund) throw new Error('退费记录不存在');
    
    // 只有待处理状态的退费记录可以处理
    if (refund.status !== 0) {
      throw new Error('只有待处理状态的退费申请可以处理');
    }
    
    // 更新退费记录状态
    await refundCollection.doc(id).update({
      status,
      remarks: remarks || refund.remarks,
      update_date: new Date()
    });
    
    return {
      id,
      success: true
    };
  },
  
  /**
   * 取消退费记录
   * @param {String} id - 退费记录ID
   * @returns {Object} 取消结果
   */
  async cancelRefund(id) {
    if (!id) throw new Error('退费记录ID不能为空');
    
    // 检查退费记录是否存在
    const refund = await refundCollection.doc(id).get().then(res => res.data[0]);
    if (!refund) throw new Error('退费记录不存在');
    
    // 只有待处理状态的退费记录可以取消
    if (refund.status !== 0) {
      throw new Error('只有待处理状态的退费申请可以取消');
    }
    
    // 取消退费记录
    await refundCollection.doc(id).remove();
    
    return {
      id,
      success: true
    };
  },
  
  /**
   * 基于考勤自动计算退费金额
   * @param {String} enrollment_id - 报名ID
   * @param {String} period_start - 退费周期开始日期
   * @param {String} period_end - 退费周期结束日期
   * @returns {Object} 退费计算结果
   */
  async calculateRefundByAttendance(enrollment_id, period_start, period_end) {
    if (!enrollment_id) throw new Error('报名ID不能为空');
    if (!period_start) throw new Error('退费周期开始日期不能为空');
    if (!period_end) throw new Error('退费周期结束日期不能为空');
    
    // 验证日期范围
    const startDate = new Date(period_start);
    startDate.setHours(0, 0, 0, 0);
    
    const endDate = new Date(period_end);
    endDate.setHours(23, 59, 59, 999);
    
    if (startDate > endDate) {
      throw new Error('开始日期不能晚于结束日期');
    }
    
    // 获取报名记录
    const enrollment = await db.collection('enrollment')
      .aggregate()
      .match({
        _id: enrollment_id
      })
      .lookup({
        from: 'student',
        localField: 'student_id',
        foreignField: '_id',
        as: 'student'
      })
      .lookup({
        from: 'course',
        localField: 'course_id',
        foreignField: '_id',
        as: 'course'
      })
      .project({
        _id: 1,
        student_id: 1,
        course_id: 1,
        fee: 1,
        discount: 1,
        student: { $arrayElemAt: ['$student', 0] },
        course: { $arrayElemAt: ['$course', 0] }
      })
      .end()
      .then(res => res.data[0]);
    
    if (!enrollment) throw new Error('报名记录不存在');
    
    // 获取该时间段内的考勤记录
    const attendances = await db.collection('attendance')
      .where({
        student_id: enrollment.student_id,
        course_id: enrollment.course_id,
        date: dbCmd.gte(startDate).and(dbCmd.lte(endDate))
      })
      .get()
      .then(res => res.data);
    
    // 获取课程上课时间信息，计算总课程数
    const course = enrollment.course;
    const weekdays = course.weekdays || [];
    
    // 计算周期内总课程数
    let totalDays = 0;
    let currentDate = new Date(startDate);
    
    while (currentDate <= endDate) {
      // 获取星期几 (0-6，0表示星期日)
      const day = currentDate.getDay();
      // 将星期日转换为7，与schema中的定义对应
      const weekday = day === 0 ? 7 : day;
      
      if (weekdays.includes(weekday)) {
        totalDays++;
      }
      
      // 增加一天
      currentDate.setDate(currentDate.getDate() + 1);
    }
    
    // 出勤和请假数
    const presentCount = attendances.filter(a => a.status === 1).length;
    const leaveCount = attendances.filter(a => a.status === 2).length;
    
    // 缺勤数
    const absentCount = totalDays - presentCount - leaveCount;
    
    // 计算退费金额
    // 按照缺勤次数计算退费金额，前提是有缴费记录
    // 获取该时间段的缴费记录
    const payments = await db.collection('payment')
      .where({
        enrollment_id,
        status: 1, // 已缴费状态
        period_start: dbCmd.lte(endDate),
        period_end: dbCmd.gte(startDate)
      })
      .get()
      .then(res => res.data);
    
    if (payments.length === 0) {
      return {
        success: false,
        message: '该时间段内没有缴费记录',
        refundData: null
      };
    }
    
    // 计算该时间段内的缴费总额
    const totalPaid = payments.reduce((sum, payment) => sum + payment.amount, 0);
    
    // 计算单次课程费用
    let perClassFee = 0;
    
    if (course.fee_type === 1) {
      // 月度收费
      perClassFee = totalPaid / totalDays;
    } else if (course.fee_type === 2 && course.fee_count) {
      // 按次数收费
      perClassFee = totalPaid / course.fee_count;
    }
    
    // 应退费金额 = 缺勤次数 * 单次课程费用
    const refundAmount = Math.round(absentCount * perClassFee);
    
    // 构建退费计算结果
    return {
      success: true,
      refundData: {
        student_id: enrollment.student_id,
        course_id: enrollment.course_id,
        enrollment_id: enrollment._id,
        payment_id: payments[0]._id, // 使用第一个缴费记录ID
        amount: refundAmount,
        period_start: startDate,
        period_end: endDate,
        refund_reason: `基于考勤自动计算：总课程${totalDays}次，出勤${presentCount}次，请假${leaveCount}次，缺勤${absentCount}次`,
        student_name: enrollment.student?.name || '',
        course_name: course.name || '',
        attendance_stats: {
          total_days: totalDays,
          present_count: presentCount,
          leave_count: leaveCount,
          absent_count: absentCount
        }
      }
    };
  },
  
  /**
   * 查询可退费的记录
   * @param {String} start_date - 开始日期
   * @param {String} end_date - 结束日期
   * @returns {Array} 可退费记录列表
   */
  async getRefundableRecords(start_date, end_date) {
    if (!start_date) throw new Error('开始日期不能为空');
    if (!end_date) throw new Error('结束日期不能为空');
    
    // 验证日期范围
    const startDate = new Date(start_date);
    startDate.setHours(0, 0, 0, 0);
    
    const endDate = new Date(end_date);
    endDate.setHours(23, 59, 59, 999);
    
    if (startDate > endDate) {
      throw new Error('开始日期不能晚于结束日期');
    }
    
    // 获取所有有效的报名记录
    const enrollments = await db.collection('enrollment')
      .aggregate()
      .match({
        status: 1
      })
      .lookup({
        from: 'student',
        localField: 'student_id',
        foreignField: '_id',
        as: 'student'
      })
      .lookup({
        from: 'course',
        localField: 'course_id',
        foreignField: '_id',
        as: 'course'
      })
      .project({
        _id: 1,
        student_id: 1,
        course_id: 1,
        student: { $arrayElemAt: ['$student', 0] },
        course: { $arrayElemAt: ['$course', 0] }
      })
      .end()
      .then(res => res.data);
    
    // 获取时间范围内的缴费记录
    const payments = await db.collection('payment')
      .where({
        status: 1, // 已缴费状态
        period_start: dbCmd.lte(endDate),
        period_end: dbCmd.gte(startDate)
      })
      .get()
      .then(res => res.data);
    
    // 按报名ID分组缴费记录
    const paymentsByEnrollment = {};
    
    payments.forEach(payment => {
      if (!paymentsByEnrollment[payment.enrollment_id]) {
        paymentsByEnrollment[payment.enrollment_id] = [];
      }
      paymentsByEnrollment[payment.enrollment_id].push(payment);
    });
    
    // 为每个报名记录计算退费金额
    const refundableRecords = [];
    
    for (const enrollment of enrollments) {
      // 只处理有缴费记录的报名
      if (!paymentsByEnrollment[enrollment._id]) continue;
      
      // 计算退费金额
      const result = await this.calculateRefundByAttendance(
        enrollment._id,
        start_date,
        end_date
      );
      
      if (result.success && result.refundData.amount > 0) {
        refundableRecords.push(result.refundData);
      }
    }
    
    return refundableRecords;
  }
}; 